﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Web.UI.Design;
using System.IO;
using System.Text.RegularExpressions;
using System.Reflection;
using System.Web.Services;

namespace AjaxSnippets.Design
{
    public partial class ChooseWebMethodWizardStep : WizardStep
    {

        private Label label2;
        private ComboBox WebMethodsComboBox;
        private Label label1;
        private Button FindAsmxFileButton;
        private TextBox WebServiceVirtualPathTextBox;
        private Label WebServiceMethodErrorLabel;
        private ConfigureSnippetCallbackWizard _Wizard; 
       
        public override string StepTitle
        {
            get { return "Choose a web service method"; }
        }

        public override bool CanFinish
        {
            get { return false; }
        }

        public ChooseWebMethodWizardStep(ConfigureSnippetCallbackWizard wizard)
        {
            _Wizard = wizard;
            InitializeComponent();
        }
        private void InitializeComponent()
        {
            this.label2 = new System.Windows.Forms.Label();
            this.WebMethodsComboBox = new System.Windows.Forms.ComboBox();
            this.label1 = new System.Windows.Forms.Label();
            this.FindAsmxFileButton = new System.Windows.Forms.Button();
            this.WebServiceVirtualPathTextBox = new System.Windows.Forms.TextBox();
            this.WebServiceMethodErrorLabel = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // label2
            // 
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(17, 74);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(111, 13);
            this.label2.TabIndex = 11;
            this.label2.Text = "Web Service Method:";
            // 
            // WebMethodsComboBox
            // 
            this.WebMethodsComboBox.DisplayMember = "Name";
            this.WebMethodsComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this.WebMethodsComboBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.WebMethodsComboBox.FormattingEnabled = true;
            this.WebMethodsComboBox.Location = new System.Drawing.Point(17, 93);
            this.WebMethodsComboBox.Name = "WebMethodsComboBox";
            this.WebMethodsComboBox.Size = new System.Drawing.Size(544, 24);
            this.WebMethodsComboBox.TabIndex = 10;
            this.WebMethodsComboBox.SelectedIndexChanged += new System.EventHandler(this.WebMethodsComboBox_SelectedIndexChanged);
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(14, 17);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(129, 13);
            this.label1.TabIndex = 9;
            this.label1.Text = "Web Service Virtual Path:";
            // 
            // FindAsmxFileButton
            // 
            this.FindAsmxFileButton.Location = new System.Drawing.Point(528, 33);
            this.FindAsmxFileButton.Name = "FindAsmxFileButton";
            this.FindAsmxFileButton.Size = new System.Drawing.Size(33, 22);
            this.FindAsmxFileButton.TabIndex = 8;
            this.FindAsmxFileButton.Text = "...";
            this.FindAsmxFileButton.UseVisualStyleBackColor = true;
            this.FindAsmxFileButton.Click += new System.EventHandler(this.FindAsmxFileButton_Click);
            // 
            // WebServiceVirtualPathTextBox
            // 
            this.WebServiceVirtualPathTextBox.Enabled = false;
            this.WebServiceVirtualPathTextBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.WebServiceVirtualPathTextBox.Location = new System.Drawing.Point(17, 33);
            this.WebServiceVirtualPathTextBox.Name = "WebServiceVirtualPathTextBox";
            this.WebServiceVirtualPathTextBox.Size = new System.Drawing.Size(505, 22);
            this.WebServiceVirtualPathTextBox.TabIndex = 7;
            this.WebServiceVirtualPathTextBox.TextChanged += new System.EventHandler(this.WebServiceVirtualPathTextBox_TextChanged);
            // 
            // WebServiceMethodErrorLabel
            // 
            this.WebServiceMethodErrorLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.WebServiceMethodErrorLabel.ForeColor = System.Drawing.Color.Red;
            this.WebServiceMethodErrorLabel.Location = new System.Drawing.Point(17, 124);
            this.WebServiceMethodErrorLabel.Name = "WebServiceMethodErrorLabel";
            this.WebServiceMethodErrorLabel.Size = new System.Drawing.Size(505, 51);
            this.WebServiceMethodErrorLabel.TabIndex = 12;
            this.WebServiceMethodErrorLabel.Text = "Could not load the web service type, you can try compiling your web application a" +
                "nd closing then reopening your snippet before running this wizard\r\n";
            this.WebServiceMethodErrorLabel.Visible = false;
            // 
            // ChooseWebMethodWizardStep
            // 
            this.Controls.Add(this.WebServiceMethodErrorLabel);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.WebMethodsComboBox);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.FindAsmxFileButton);
            this.Controls.Add(this.WebServiceVirtualPathTextBox);
            this.Name = "ChooseWebMethodWizardStep";
            this.Size = new System.Drawing.Size(572, 188);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        private void FindAsmxFileButton_Click(object sender, EventArgs e)
        {
            WebServiceVirtualPathTextBox.Text = _Wizard.WebFormsBuilderUIService.BuildUrl(this, WebServiceVirtualPathTextBox.Text, "~/", "Choose Web Service (*.asmx)", "ASMX Files|*.asmx", UrlBuilderOptions.NoAbsolute);
            IProjectItem item = _Wizard.WebApplication.GetProjectItemFromUrl(WebServiceVirtualPathTextBox.Text);

            if (Path.GetExtension(item.PhysicalPath).Equals(".asmx", StringComparison.OrdinalIgnoreCase))
            {
                string asmxFileContents = File.ReadAllText(item.PhysicalPath);
                Regex typeRegex = new Regex(@"(?<=<%.+Class(\s+)?=(\s+)?\x22)([^\x22]+)(?=\x22.+%>)");
                Match match = typeRegex.Match(asmxFileContents);
                if (match.Success)
                {
                    Type asmxType = Type.GetType(match.Value.Trim(), false, true);
                    this.WebServiceMethodErrorLabel.Visible = (asmxType == null);
                    if (asmxType != null)
                    {
                        _Wizard.WebMethods = (from method in asmxType.GetMethods()
                                             let attr = method.GetCustomAttributes(typeof(WebMethodAttribute), true)
                                             where attr != null && attr.Length > 0 && method.GetParameters().Length > 0
                                             orderby method.Name
                                             select method).ToList();

                        if (_Wizard.WebMethods.Count > 0)
                        {
                            this.WebMethodsComboBox.Items.Clear();
                            foreach (MethodInfo method in _Wizard.WebMethods)
                            {
                                this.WebMethodsComboBox.Items.Add(FormatMethodSignature(method));

                            }
                            this.WebMethodsComboBox.SelectedIndex = 0;
                            _Wizard.SelectedWebMethod = _Wizard.WebMethods[WebMethodsComboBox.SelectedIndex];

                        }
                    }
                }
            }
        }

        private string FormatMethodSignature(MethodInfo method)
        {
            ParameterInfo[] parms = method.GetParameters();
            string joinedParms = null;
            if (parms != null && parms.Length > 0)
            {
                joinedParms = String.Join(", ", Array.ConvertAll<ParameterInfo, string>(method.GetParameters(), new Converter<ParameterInfo, string>((info) => { return info.Name; })));
            }
            return String.Format("{0}({1})", method.Name, joinedParms);
        }

        private void UpdateWizardButtonState()
        {
            _Wizard.ButtonNext.Enabled = !String.IsNullOrEmpty(WebServiceVirtualPathTextBox.Text) &&
                                         this.WebMethodsComboBox.SelectedItem != null;
        }

        private void WebServiceVirtualPathTextBox_TextChanged(object sender, EventArgs e)
        {
            UpdateWizardButtonState();
        }

        private void WebMethodsComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            _Wizard.SelectedWebMethod = _Wizard.WebMethods[WebMethodsComboBox.SelectedIndex];
            UpdateWizardButtonState();
        }

        public override void OnActive()
        {
            UpdateWizardButtonState();
        }

        public override void OnNext()
        {
            SetWizardSelectedValues();
        }

        public override void OnPrevious()
        {
            SetWizardSelectedValues();
        }

        public override void OnFinish()
        {
            SetWizardSelectedValues();
        }

        private void SetWizardSelectedValues()
        {
            _Wizard.SelectedWebMethod = _Wizard.WebMethods[WebMethodsComboBox.SelectedIndex];
            _Wizard.SelectedWebServiceVirtualPath = this.WebServiceVirtualPathTextBox.Text;
        }

    }
}
